﻿#include "C3fdChartWidget.h"
#include <QPen>
#include <QDebug>
#include <QGridLayout>
#include <QPointF>
#include <qwt_plot_canvas.h>
#include <qwt_symbol.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_renderer.h>

namespace MainWidget
{

	C3fdChartWidget::C3fdChartWidget(QStringList seriesTitles, bool showPoint, QWidget *parent)
		: QWidget(parent), m_ShowPoint(showPoint), m_SeriesTitles(seriesTitles)
	{
		setFocusPolicy(Qt::ClickFocus);

		QGridLayout *lay = new QGridLayout(this);
		lay->setMargin(0);
		lay->setSpacing(0);
		this->setLayout(lay);

		QGridLayout *lay1 = nullptr;
		if (m_ChartWidget == nullptr)
		{
			m_ChartWidget = new QWidget;
			m_ChartWidget->setMinimumSize(10, 10);
			m_ChartWidget->setContentsMargins(2, 2, 2, 2);
			m_ChartWidget->setObjectName("FrameWidget");
			lay1 = new QGridLayout(m_ChartWidget);
			lay1->setMargin(0);
			lay1->setSpacing(0);

			lay->addWidget(m_ChartWidget);
		}

		initPlot();

		if (m_Plot != nullptr && lay1 != nullptr)
		{
			lay1->addWidget(m_Plot);
		}
	}

	C3fdChartWidget::~C3fdChartWidget()
	{
		if (m_Plot != nullptr)
		{
			delete m_Plot;
			m_Plot = nullptr;
		}
	}

	QStringList C3fdChartWidget::getSeriesTitles()
	{
		return m_SeriesTitles;
	}

	void C3fdChartWidget::appendData(QVector<double> data)
	{
		int count = m_Curves.size();
		if (count != data.size() - 1)
		{
			return;
		}
		for (int i = 0; i < count; i++)
		{
			m_Datas[i].append(QPointF(data.at(0), data.at(i + 1)));
			m_Curves.at(i)->detach();
			m_Curves.at(i)->setSamples(m_Datas.at(i));
			m_Curves.at(i)->attach(m_Plot);
		}
		rePlot();
	}

	void C3fdChartWidget::setData(QList<QVector<double>> data)
	{
		if (data.isEmpty())
		{
			return;
		}
		int count = m_Curves.size();
		for (int i = 0; i < count; i++)
		{
			m_Datas[i].clear();
		}
		for (auto d : data)
		{
			if (d.isEmpty())
			{
				return;
			}

			if (count != d.size() - 1)
			{
				return;
			}
			for (int i = 0; i < count; i++)
			{
				m_Datas[i].append(QPointF(d.at(0), d.at(i + 1)));
			}
		}

		for (int i = 0; i < count; i++)
		{
			m_Curves.at(i)->detach();
			m_Curves.at(i)->setSamples(m_Datas.at(i));
			m_Curves.at(i)->attach(m_Plot);
		}
		rePlot();
	}

	void C3fdChartWidget::saveImage(QString filePath, int width, int height, Common::AspectRatioMode mode, int quality)
	{
		if (width <= 0)
		{
			width = m_Plot->width();
		}
		if (height <= 0)
		{
			height = m_Plot->height();
		}
		switch (mode)
		{
		case Common::AspectRatioMode::KeepWidth:
			height = (int)(width * 1.000 / m_Plot->width() * m_Plot->height());
			break;
		case Common::AspectRatioMode::KeepHeight:
			width = (int)(height * 1.000 / m_Plot->height() * m_Plot->width());
			break;
		default:
			break;
		}
		QPixmap pixmap(width, height);
		QwtPlotRenderer render;
		render.renderTo(m_Plot, pixmap);
		if (!filePath.endsWith(".jpg"))
		{
			filePath += ".jpg";
		}
		if (quality < -1)
		{
			quality = -1;
		}
		else if (quality > 100)
		{
			quality = 100;
		}
		pixmap.save(filePath, "JPG", quality);
	}

	void C3fdChartWidget::legendCheckedSlot(const QVariant &itemInfo, bool on, int index)
	{
		Q_UNUSED(index);
		QwtPlotItem *plotItem = m_Plot->infoToItem(itemInfo);
		if (plotItem)
		{
			showCurve(plotItem, on);
		}
	}

	void C3fdChartWidget::showCurve(QwtPlotItem *item, bool on)
	{

		item->setVisible(on);

		QwtLegend *lgd = qobject_cast<QwtLegend *>(m_Plot->legend());

		QList<QWidget *> legendWidgets = lgd->legendWidgets(m_Plot->itemToInfo(item));

		if (legendWidgets.size() == 1)
		{
			QwtLegendLabel *legendLabel = qobject_cast<QwtLegendLabel *>(legendWidgets[0]);
			if (legendLabel)
				legendLabel->setChecked(on);
		}
		rePlot();
	}

	void C3fdChartWidget::showCurve(QString title)
	{
		QwtLegend *legend = qobject_cast<QwtLegend *>(m_Plot->legend());
		for (auto item : m_Plot->itemList())
		{
			QList<QWidget *> legendWidgets = legend->legendWidgets(m_Plot->itemToInfo(item));
			if (legendWidgets.size() == 1)
			{
				QwtLegendLabel *legendLabel = qobject_cast<QwtLegendLabel *>(legendWidgets[0]);
				if (legendLabel == nullptr)
				{
					continue;
				}
				auto text = legendLabel->text().text();

				if (text == title)
				{
					legendLabel->setChecked(true);
					item->setVisible(true);
				}
				else
				{
					legendLabel->setChecked(false);
					item->setVisible(false);
				}
			}
		}
	}

	void C3fdChartWidget::enableFocusSignal(bool enable)
	{
		m_EnableFocusSignal = enable;
	}

	void C3fdChartWidget::enableLegendCheck(bool enable)
	{
		m_EnableLegendCheck = enable;
	}

	void C3fdChartWidget::clearAllCurve()
	{
		for (auto curve : m_Curves) {
			curve->detach();
		}
		rePlot();
	}

	void C3fdChartWidget::focusOutEvent(QFocusEvent *event)
	{
		if (m_EnableFocusSignal) {
			m_IsFocus = false;
			update();
		}
	}

	void C3fdChartWidget::paintEvent(QPaintEvent *event)
	{
		if (m_EnableFocusSignal && m_IsFocus)
		{
			this->setStyleSheet("#FrameWidget{border:1px solid green;}");
		}
		else
		{
			this->setStyleSheet("#FrameWidget{border:none;}");
		}
		QWidget::paintEvent(event);
	}

	void C3fdChartWidget::focusInEvent(QFocusEvent *event)
	{
		if (m_EnableFocusSignal) {
			m_IsFocus = true;
			emit focusInSig(this);
		}
	}

	void C3fdChartWidget::initPlot()
	{
		if (m_SeriesTitles.size() < 2)
		{
			return;
		}
		m_Plot = new QwtPlot(m_ChartWidget);
		m_Plot->detachItems();
		m_Plot->setMinimumSize(10, 10);

		// m_Plot->setAxisScale(QwtPlot::xBottom, 0, 100, 10);
		// m_Plot->setAxisScale(QwtPlot::yLeft, 0, 10, 2);
		m_Plot->setAxisAutoScale(QwtPlot::xBottom, true);
		m_Plot->setAxisAutoScale(QwtPlot::yLeft, true);
		m_Plot->setAxisLabelRotation(QwtPlot::xBottom, 45);
		m_Plot->setAxisTitle(QwtPlot::xBottom, m_SeriesTitles.at(0));
		// m_Plot->setAxisTitle(QwtPlot::yLeft, m_SeriesTitles.mid(1).join(" & "));

		m_Plot->setCanvasBackground(Qt::white);

		QwtPlotCanvas *canvas = new QwtPlotCanvas();
		canvas->setLineWidth(1);
		canvas->setFrameStyle(QFrame::Box | QFrame::Plain);
		canvas->setBorderRadius(0);

		(void)new QwtPlotMagnifier(canvas); //使用滚轮放大/缩小
		(void)new QwtPlotPanner(canvas);	//使用鼠标左键平移

		QPalette canvasPalette(Qt::white);
		canvasPalette.setColor(QPalette::Foreground, Qt::white);
		canvas->setPalette(canvasPalette);
		m_Plot->setCanvas(canvas);

		QList<QColor> colors = {
			Qt::blue,
			Qt::magenta,
			Qt::green,
			Qt::cyan,
			Qt::red,
			Qt::yellow };
		m_Datas.clear();
		m_Curves.clear();

		for (int i = 1; i < m_SeriesTitles.size(); ++i)
		{
			QPen pen;
			if (i <= colors.size())
			{
				pen.setColor(colors.at(i - 1));
			}
			else
			{
				pen.setColor(QColor(i % 255, i % 255, i % 255));
			}
			pen.setWidth(2);
			pen.setStyle(Qt::SolidLine);

			/*点*/
			QVector<QPointF> data = {};
			m_Datas.push_back(data);

			/*绘制曲线*/
			QwtPlotCurve *curve = new QwtPlotCurve(m_SeriesTitles.at(i));
			curve->setSamples(m_Datas.at(i - 1));
			curve->setPen(pen);
			if (m_ShowPoint)
			{
				curve->setSymbol(new QwtSymbol(QwtSymbol::Ellipse, QBrush(Qt::yellow), QPen(Qt::red, 2), QSize(8, 8)));
				curve->setStyle(QwtPlotCurve::CurveStyle::Dots);
			}

			curve->setStyle(QwtPlotCurve::Lines);
			curve->setCurveAttribute(QwtPlotCurve::Fitted);
			curve->attach(m_Plot);
			curve->setCurveAttribute(QwtPlotCurve::Fitted, false); //曲线光滑
			curve->setLegendAttribute(curve->LegendShowLine);

			m_Curves.push_back(curve);
		}

		/*添加网格*/
		QwtPlotGrid *grid = new QwtPlotGrid();
		grid->enableX(true); //设置网格线
		grid->enableY(true);
		grid->setMajorPen(Qt::black, 0, Qt::DotLine);
		grid->attach(m_Plot);

		/*添加图例*/
		QwtLegend *legend = new QwtLegend();
		m_Plot->insertLegend(legend, QwtPlot::TopLegend);
		connect(legend, SIGNAL(checked(const QVariant &, bool, int)), this, SLOT(legendCheckedSlot(const QVariant &, bool, int)));

		rePlot();
	}

	void C3fdChartWidget::rePlot()
	{
		if (m_Plot == nullptr) {
			return;
		}
		if (m_EnableLegendCheck) {
			QwtLegend *legend = qobject_cast<QwtLegend *>(m_Plot->legend());
			if (legend == nullptr) {
				return;
			}
			if (legend->defaultItemMode() != QwtLegendData::Checkable) {
				legend->setDefaultItemMode(QwtLegendData::Checkable); //图例可被点击
			}
			for (auto item : m_Plot->itemList())
			{
				QList<QWidget *> legendWidgets = legend->legendWidgets(m_Plot->itemToInfo(item));
				if (legendWidgets.size() == 1)
				{
					QwtLegendLabel *legendLabel = qobject_cast<QwtLegendLabel *>(legendWidgets[0]);
					if (item->isVisible()) {
						legendLabel->setChecked(true);
					}
					else {
						legendLabel->setChecked(false);
					}
				}
			}
		}
		m_Plot->replot();
	}

}
